package com.davfx.httpnio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

final class Connecter {
	
	private final Worker worker;
	
	public Connecter(Worker worker) {
		this.worker = worker;
	}
	
	public Connection connect(final String host, final int port) {
		final BasicConnection connection = new BasicConnection(worker);
		worker.add(new SelectorVisitor() {
			@Override
			public void visit(final Selector selector) {
				if (connection.isClosed()) {
					return;
				}
				try {
					final SocketChannel channel = SocketChannel.open();
					channel.configureBlocking(false);
					SelectionKey inboundKey = channel.register(selector, SelectionKey.OP_CONNECT);
					inboundKey.attach(new SelectionKeyVisitor() {
						@Override
						public void visit(SelectionKey key) {
							if (!key.isConnectable()) {
								return;
							}
							
							if (connection.isClosed()) {
								try {
									channel.close();
								} catch (IOException e) {
								}
								return;
							}
							
							try {
								channel.finishConnect();
								connection.connected(selector, channel);
							} catch (IOException e) {
								try {
									channel.close();
								} catch (IOException ee) {
								}
								connection.failed(e);
							}
						}
					});
					try {
						channel.connect(new InetSocketAddress(host, port));
					} catch (IOException e) {
						inboundKey.cancel();
						throw e;
					}
				} catch (IOException e) {
					connection.failed(e);
				}
			}
		});
		return connection;
	}
}
